//下载模板 选择模板使用  下载那个模板？计划？
// 拿到  https://api.github.com/orgs/zhufeng-cli/repos  让用户选择就行

//用过配置文件 获取模板信息(有哪些模板)？？？
import { repoList, tagList, downloadLocal, } from './utils/git';
import ora from 'ora';//进度条  命令行的loading..
let fs = require('fs');
import inquirer from 'inquirer';//命令交互
let { promisify } = require('util');
let MetalSmith = require('metalsmith'); //遍历文件夹，找需不需要渲染
//consolidate tj写的统一所有的模板引擎
let {render } = require('consolidate').ejs;
render = promisify(render);
let ncp = require('ncp');
ncp = promisify(ncp);
const path=require('path');

//封装loading
const waitFnloading = (fn, message) => async (...args) => {
    let spinner = ora(message);
    spinner.start();
    let result = await fn(...args)
    spinner.succeed();
    return result;
}

const copy = async (result, projectName) => {
    //有的时候用户可以定制下载模板中的内容，拿package.json文件为例，用户可以根据提示给项目命名、
    //设置描述等，生成最终的package.json文件 ask.json网址：https://github.com/zhu-cli/vue-template/blob/master/ask.js
    //如果没有有ask.js文件直接下载
    if (!fs.existsSync(path.join(result, 'ask.js'))) {
        //复杂的需要模板熏染 渲染后再拷贝
        //把template下的文件 拷贝到执行命令的目录下
        //在这个目录下 项目名字是否已经存在 如果存在示当前已经存在
        await ncp(result, path.resolve(projectName));
    } else {
        //复杂的模板  把git上的项目下载下来，如果有ask文件就是一个复杂的模板，我们需要用户选择，选择后编译模板  
        // metalsmith--模板编译需要这个包
        //需要渲染模板的接口：https://github.com/zhu-cli/vue-template/blob/master/package.json
        //1.让用户填信息
        // use 依次注册中间件
        // build 依次让中间件依次执行。
        await new Promise((resolve, reject) => {
            MetalSmith(__dirname) //如果你传入路径，默认遍历当前路径下的src文件夹
                .source(result)
                .destination(path.resolve(projectName))
                .use(async (files, metal, done) => {
                    // console.log(files)
                    let args = require(path.join(result, 'ask.js'));
                    let obj = await inquirer.prompt(args);
                    console.log(obj, 'obj=>用户填写的结果');//用户填写的结果
                    let meta = metal.metadata();
                    Object.assign(meta, obj);
                    delete files['ask.js'];
                    done();
                })
                .use((files, metal, done) => {
                    let obj = metal.metadata()
                    Reflect.ownKeys(files).forEach(async file => {
                        //是要处理的文件
                        if (file.includes('js') || file.includes('json')) {
                            let content = files[file].contents.toString();//文件的内容
                            if (content.includes('<%')) {
                                content = await render(content, obj);
                                files[file].contents = Buffer.from(content);//渲染结果
                            }
                        }
                    })
                    //2.让用户填写的信息取渲染模板
                    //根据用户新的输入 下载模板
                    // console.log(metal.metadata())
                    done();
                })
                .build((err) => {
                    if (err) {
                        reject()
                    } else {
                        resolve();
                    }
                })
        })
    }
}

// zf-ci  install 项目
let install = async (projectName) => {
    let loading = ora('fetching template ......');
    loading.start();//开始请求远程仓库loading
    // 获取远程仓库的信息
    let list = await repoList();
    console.log(list, 'list远程仓库的信息打印。。。');
    loading.succeed(); //结束请求远程仓库loading
    list = list.map(({ name }) => name);

    // let list = await waitFnloading(repoList, 'fetch template ....')();
    // list = list.map(item => item.name);

    console.log(list, 'list的名字..');
    // inquirer 用户选那个包？交互包用。。
    // 配置弹框还是列表？
    let answer = await inquirer.prompt([{
        type: 'list', //配置需要列表还是输入框？？？
        name: 'project',//当前取到的项目名字。。
        choices: list,//要选择什么？
        questions: 'pleace choice template'
    }]);
    console.log(answer, 'answer=>拿到用户选择的结果', answer.project, '拿到用户选择的项目名字？');
    //拿到当前项目
    let project = answer.project;
    console.log("project", project);

    // 拿到当前项目以后拿到每个项目模板的tag..具体版本
    //获取当前的项目的版本号
    loading = ora('fetching tag ......');//开始请求项目的版本老套路
    loading.start();
    list = await tagList(project);
    console.log("tags=》拿到当前项目以后拿到每个项目模板的tag..具体版本", list)
    loading.succeed();//结束请求老套路

    list = list.map(({ name }) => name);
    let answer2 = await inquirer.prompt([{
        type: 'list',
        name: 'tag',
        choices: list,
        questions: 'pleace choice tag'
    }]);
    let tag = answer2.tag;
    console.log("tags=》拿到当前项目用户选择项目的的具体版本tag是多少?", tag);

    console.log(project, tag, '打印拿到额项目和版本具体是多少??');
    //下载文件(先下载到缓存区文件中)  之后用到直接从缓存里拷贝
    //zf-cli init  之后可以把下载好的文件直接从缓存到桌面上。
    //下载中... 
    loading = ora('download project ......');
    loading.start();
    let result = await downloadLocal(project, tag);
    loading.succeed();
    console.log(result, 'result=>下载的目录当前下载的是谁？？？')
     copy(result, projectName)
  

}


// result 是模板下载的原路径。。。
//拿到下载的目录 直接拷贝当前正在执行的目录下即可    ncp拷贝
// 复杂的要需要模板引擎渲染，渲染后再拷贝。。




export default install;